package com.dragon.sdgp.util.regexpDecode;

import com.dragon.sdgp.util.CommonUtil;
import com.dragon.sdgp.util.regexpDecode.handler.MetaData;
import com.dragon.sdgp.util.regexpDecode.handler.PreparationHandler;

import java.util.ArrayList;
import java.util.List;

/**
 * @AUTHOR : Dragon_Yang
 * @File : RegExpDataGenerateUtil
 * @DESCRIPTION : 解析正则表达式生成数据
 * @DATE : 2023/3/2 14:07
 */
public class RegExpDataGenerateUtil {

    private static List<MetaData> metaData = null;

    public static void main(String[] args) {
        RegExpDataGenerateUtil.createDataList(10, "[0-9a-zA-Z]").forEach(System.out::println);
    }

    private static void decode(String exp){
        metaData = PreparationHandler.preDecode(exp);
    }

    private static String createData(){
        StringBuilder stringBuilder = new StringBuilder();
        metaData.stream().forEach(metaDataItem -> {
            int num = CommonUtil.getRandom(metaDataItem.getMinCount(), metaDataItem.getMaxCount() + 1);
            if(metaDataItem.getChars() == null){
                int min = 0, max = 0;
                if(metaDataItem.getSpan().size() != 0 && metaDataItem.getOption().size() != 0){
                    max = 2;
                }else if(metaDataItem.getSpan().size() != 0 && metaDataItem.getOption().size() == 0){
                    max = 1;
                }else if(metaDataItem.getSpan().size() == 0 && metaDataItem.getOption().size() != 0){
                    min = 1;
                    max = 2;
                }
                for (int i = 0; i < num; i++) {
                    if(!metaDataItem.isNot()){
                        int rand = CommonUtil.getRandom(min, max);
                        switch (rand){
                            case 0:{
                                int index = CommonUtil.getRandom(metaDataItem.getSpan().size() / 2) * 2;
                                stringBuilder.append((char) CommonUtil.getRandom(metaDataItem.getSpan().get(index), metaDataItem.getSpan().get(index + 1) + 1));
                                break;
                            }
                            case 1:{
                                int len = metaDataItem.getOption().size();
                                stringBuilder.append((char) metaDataItem.getOption().get(CommonUtil.getRandom(len)).intValue());
                                break;
                            }
                        }
                    }else {
                        //TODO 策略有待优化
                        int t = CommonUtil.getRandom(0, 4);
                        int c = -1;
                        if(t == 0){
                            c = CommonUtil.getRandom(19968, 40869 + 1);
                        }else if(t == 1){
                            c = CommonUtil.getRandom(48, 57 + 1);
                        }else if(t == 2){
                            c = CommonUtil.getRandom(97, 122 + 1);
                        }else if(t == 3){
                            c = CommonUtil.getRandom(65, 90 + 1);
                        }
                        for (int j = 0; j < metaDataItem.getSpan().size(); j += 2) {
                            if(metaDataItem.getSpan().get(j) <= c && c <= metaDataItem.getSpan().get(j + 1)) {
                                i--;
                                continue;
                            }
                        }
                        for (Integer integer : metaDataItem.getOption()) {
                            if(integer == c){
                                i--;
                                continue;
                            }
                        }
                        stringBuilder.append((char) c);
                    }
                }
            }else {
                for (int i = 0; i < num; i++) {
                   stringBuilder.append(metaDataItem.getChars());
                }
            }
        });
        return stringBuilder.toString();
    }

    public static List<String> createDataList(int count, String exp){
        decode(exp);
        List<String> dataList = new ArrayList<>(count);
        while (count-- > 0){
            dataList.add(createData());
        }
        return dataList;
    }
}
